
//
// 120815 - (AH) - Created.
// 120919 - (AH) - (Midtun) publish now accepts who is publishing.
// 121014 - (AH) - (Midtun *) getListeners().
//

package org.soekrat.conversationevent;

import java.util.ArrayList;
import java.util.List;

import org.soekrat.Log;

/**
 * <p>
 *   Utility for publishing 
 *   {@link ConversationEvent}s of use for
 *   {@link ConversationEventSource}s that can not extends
 *   {@link AbstractConversationEventSource}.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class ConversationEventPublisher
{
  private transient List<ConversationListener> m_listeners=null;

  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public ConversationEventPublisher(){}

  /**
   * <p>
   *   Adds
   *   {@link ConversationListener}.
   * </p>
   * @param l Listener to add.
   */
  public synchronized void addListener(ConversationListener l) 
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
  
    if (m_listeners==null) m_listeners=new ArrayList<ConversationListener>();
    m_listeners.add(l);  
  }

  /**
   * <p>
   *   Removes
   *   {@link ConversationListener}.
   * </p>
   * @param l Listener to remove.
   */
  public synchronized void removeListener(ConversationListener l)
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
  
    if (m_listeners==null) return;
    m_listeners.remove(l);
  }
  
  /**
   * <p>
   *   Gets listeners.
   * </p>
   * @return Listeners.
   */
  public synchronized List<ConversationListener> getListeners()
  {
    List<ConversationListener> retVal=new ArrayList<ConversationListener>();
    if (m_listeners!=null) retVal.addAll(m_listeners);
    return retVal;
  }
  
  /**
   * <p>
   *   Gets number of listeners.
   * </p>
   * @return Count.
   */
  public int getListenerCount()
  {
    return (m_listeners==null) ? 0 : m_listeners.size();
  }
  
  

  /**
   * <p>
   *   Publishes event.
   * </p>
   * @param source Source publishing the event.
   * @param e      Event to publish.
   */
  public void publish(ConversationEvent e)
  {
    Log.log(c_log, this, "publish", "e="+e);
    
    Log.log(c_log, this, "publish", "publish to "+
      getListenerCount()+" listeners");
    
    if (m_listeners==null) return;
    
    List<ConversationListener> l=null;
    synchronized(this)
    {
      l=new ArrayList<ConversationListener>(m_listeners);
    }
    
    for (ConversationListener curr : l)
    {
      Log.log(c_log, this, "publish", "  listener: "+
        curr.getClass().getName());
      curr.receive(e);
    }
  }
  
  private static final boolean c_log=true;
  
}
